package com.token.sql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

/**
 * 预编译SQL
 * @author chenjianxiong 2020/2/17
 */
public class PrepareSql {
    private PreparedStatement pst;
    private Connection conn;
    public PrepareSql(IntegrateSql iSql){
        this.conn = iSql.getCon();
    }
    /**
     * 预编SQL语句:select,update,insert;
     * @param sql sql语句
     * @throws SQLException 错误抛出
     */
    public void setPrepare(String sql) throws SQLException{
        pst = conn.prepareStatement(sql);
    }

    /**
     * 预编SQL语句:select,update,insert;
     * @param sql sql语句
     * @throws SQLException 错误抛出
     */
    public void setPrepare(StringBuffer sql) throws SQLException{
        pst = conn.prepareStatement(sql.toString());
    }

    /**
     * 静态SQL模式，可获取返回ID的写法。
     * 获取ID时，请使用getGeneratedKeys函数获取
     * @param sql SQL
     * @throws SQLException 错误抛出
     */
    public void setPrepareReturnKey(String sql) throws SQLException{
        pst = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
    }

    /**
     *
     * @param index 索引值
     * @param v 值
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,String v) throws SQLException{
        pst.setString(index, v);
    }

    /**
     *
     * @param index 索引值
     * @param v int
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,int v) throws SQLException{
        pst.setInt(index, v);
    }
    /**
     *
     * @param index 索引值
     * @param v Object
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,Object v) throws SQLException{
        pst.setObject(index, v);
    }
    /**
     *
     * @param index 索引值
     * @param v Timestamp
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,Timestamp v) throws SQLException{
        pst.setTimestamp(index, v);
    }
    /**
     *
     * @param index 索引值
     * @param date date
     * @param isTimestamp isTimestamp
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index, Date date, boolean isTimestamp) throws SQLException{
        if(isTimestamp){
            pst.setTimestamp(index, new Timestamp(date.getTime()));
        }else{
            pst.setDate(index, (java.sql.Date) date);
        }
    }
    /**
     *
     * @param index 索引值
     * @param date Date
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,Date date) throws SQLException{
        this.setPstValue(index, date, true);
    }

    /**
     *
     * @param index 索引值
     * @param v double
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,double v) throws SQLException{
        pst.setDouble(index, v);
    }
    /**
     *
     * @param index 索引值
     * @param v long
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,long v) throws SQLException{
        pst.setLong(index, v);
    }
    /**
     *
     * @param index 索引值
     * @param v float
     * @throws SQLException 错误抛出
     */
    public void setPstValue(int index,float v) throws SQLException{
        pst.setFloat(index, v);
    }
    /**
     *
     * @throws SQLException 错误抛出
     */
    public void addBatch() throws SQLException{
        pst.addBatch();
    }
    /**
     *
     * @param sql SQL
     * @throws SQLException 错误抛出
     */
    public void addBatch(String sql) throws SQLException{
        pst.addBatch(sql);
    }
    /**
     *
     * @return int
     * @throws SQLException 错误抛出
     */
    public int executeUpdate() throws SQLException{
        return pst.executeUpdate();
    }
    /**
     *
     * @return int[]
     * @throws SQLException 错误抛出
     */
    public int[] executeBatch() throws SQLException{
        return pst.executeBatch();
    }

    /**
     *
     * @return ResultSet
     * @throws SQLException 错误抛出
     */
    public ResultSet executeQuery() throws SQLException {
        return pst.executeQuery();
    }

    /**
     * 预编插入记录SQL语句
     * @param tableName 表名
     * @param fields 字段列表
     * @return String
     */
    public String insertDataStr(String tableName, List<String> fields) {
        StringBuffer instr = new StringBuffer("Insert into " + tableName + "(");
        StringBuffer valuesstr = new StringBuffer("values(");
        for (int i = 0; i < fields.size(); i++) {
            if (i != fields.size() - 1) {
                instr.append(fields.get(i)).append(",");
                valuesstr.append("?,");
            } else {
                instr.append(fields.get(i)).append(")");
                valuesstr.append("?)");
            }
        }
        instr.append(valuesstr);
        return instr.toString();

    }
    /**
     * 预编更新记录SQL语句
     * @param tableName 表名
     * @param fields 字段列表
     * @param key 主键名
     * @return String
     */
    public String updateDataStr(String tableName, List<String> fields,String key) {
        StringBuffer instr = new StringBuffer(200);
        instr.append(this.updateDataStr(tableName, fields));
        instr.append(" where ").append(key).append("=?");
        return instr.toString();
    }
    /**
     * 预编更新记录SQL语句
     * @param tableName 表名
     * @param fields 字段列表
     * @return String
     */
    public String updateDataStr(String tableName, List<String>  fields) {
        StringBuffer instr = new StringBuffer(200);
        instr.append("update ").append(tableName).append(" set ");
        for (int i = 0; i < fields.size(); i++) {
            if (i != fields.size() - 1) {
                instr.append(fields.get(i).toString()).append("=?,");
            } else {
                instr.append(fields.get(i).toString()).append("=?");
            }
        }
        return instr.toString();
    }

    /**
     * 预编更新记录SQL语句
     * @param tableName 表名
     * @param fields 字段列表
     * @param keyName 主键名
     * @throws SQLException 错误抛出
     */
    public void setUpdateFields(String tableName,List<String> fields,String keyName) throws SQLException{
        pst = conn.prepareStatement(this.updateDataStr(tableName, fields,keyName));
    }

    /**
     * 预编SQL语句:insert
     * @param tableName 表名
     * @param fields 字段数据组
     * @throws SQLException 错误抛出
     */
    public void  setInsertFields(String tableName,List<String> fields) throws SQLException{
        pst = conn.prepareStatement(this.insertDataStr(tableName, fields));
    }

    /**
     * 获取预处理
     * @return PreparedStatement
     */
    public PreparedStatement getPst() {
        return pst;
    }

    /**
     * 检索由于执行此 Statement 对象而创建的所有自动生成的键
     * @return 主键值
     * @throws SQLException 错误抛出
     */
    public String getGeneratedStringKeys() throws SQLException{
        ResultSet rs;
        rs = pst.getGeneratedKeys();
        String id = null;
        if (rs.next()) {
            id = rs.getString(1);
        }
        rs.close();
        return id;
    }

    /**
     * 检索由于执行此 Statement 对象而创建的所有自动生成的键
     * @return long
     * @throws SQLException 错误抛出
     */
    public long getGeneratedLongKeys() throws SQLException{
        ResultSet rs = pst.getGeneratedKeys();
        long id = 0;
        if (rs.next()) {
            id = rs.getLong(1);
        }
        rs.close();
        return id;
    }
    /**
     * 关闭
     */
    public void close(){
        if(pst != null){
            try {
                pst.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}
